import 'dart:convert';

import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bmfbase/BaiduMap/bmfmap_base.dart';
import 'package:flutter_bmflocation/bdmap_location_flutter_plugin.dart';
import 'package:flutter_bmflocation/flutter_baidu_location.dart';
import 'package:flutter_bmflocation/flutter_baidu_location_android_option.dart';
import 'package:flutter_bmflocation/flutter_baidu_location_ios_option.dart';

import 'package:flutter_bmfmap/BaiduMap/bmfmap_map.dart';
import 'package:flutter_bmfutils/BaiduMap/bmfmap_utils.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:loxen/api/http_util.dart';
import 'package:loxen/dialog/toast.dart';
import 'package:loxen/mode/badu_reveres_mode.dart';
import 'package:loxen/mode/baidu_map_model.dart';
import 'package:loxen/utils/color.dart';
import 'package:loxen/utils/config.dart';
import 'package:loxen/utils/string_res.dart';
import 'package:loxen/view/address/city_select_widget.dart';
import 'package:loxen/view/address/location_list_widget.dart';
import 'package:loxen/widget/fail_widget.dart';
import 'package:loxen/widget/loading_widget.dart';
import 'package:loxen/widget/my_subassembly.dart';
import 'package:provider/provider.dart';

enum MapType {
  LOADING,
  PERMISSION_FAIL,
  PERMISSION_SUCCESS,
  LOCATION_SUCCESS,
  LOCATION_FAIL,
}

class MapLocationWidget extends StatefulWidget {
  final bool showDistance;
  final List<List<BMFCoordinate>> locationList;

  const MapLocationWidget({Key key, this.showDistance = true, this.locationList}) : super(key: key);

  @override
  _MapLocationWidgetState createState() => _MapLocationWidgetState();
}

class _MapLocationWidgetState extends State<MapLocationWidget> {
  final TextEditingController _textEditingController = TextEditingController();
  final LocationFlutterPlugin _locationPlugin = LocationFlutterPlugin();
  final ValueNotifier<MapType> location = ValueNotifier(MapType.LOADING);
  final ValueNotifier<String> _city = ValueNotifier(null);
  final ValueNotifier<BDMapData> _listData = ValueNotifier(null);

  BaiduLocation _baiduLocation;
  BMFMapOptions _options;
  BMFMapController _controller;

  bool initLocationBool = false; //初始化定位
  bool getReveres = false; //查新经纬度信息
  bool getSuggestion = false; //搜索周边

  int currentIndex = 0;
  int childIndex = 0;

  Widget mainView() {
    return Column(
      children: [
        Container(
          padding: EdgeInsets.only(left: 30.w, right: 30.w),
          color: Theme.of(context).backgroundColor,
          height: 150.h,
          child: Row(
            children: [
              Padding(
                padding: EdgeInsets.only(right: 30.w),
                child: InkWell(
                  onTap: () async {
                    Navigator.of(context)
                        .push(MaterialPageRoute(
                            builder: (_) => CitySelectWidget(
                                  currentCity: _city.value,
                                  currentIndex: currentIndex,
                                  childIndex: childIndex,
                                )))
                        .then((value) {
                      if (value != null) {
                        _city.value = value['name'];
                        currentIndex = value['currentIndex'];
                        childIndex = value['childIndex'];
                      }
                    });
                  },
                  child: Row(
                    children: [
                      ValueListenableProvider<String>.value(
                        value: _city,
                        builder: (context, _) {
                          return Text(
                            context.watch<String>(),
                            style: TextStyle(fontSize: 28.sp, color: Colours.main_text),
                          );
                        },
                      ),
                      Padding(
                        padding: EdgeInsets.only(left: 12.w),
                        child: Image.asset(
                          'images/arrow_low.png',
                          width: 18.w,
                          height: 9.w,
                        ),
                      )
                    ],
                  ),
                ),
              ),
              Expanded(
                child: Container(
                  height: 88.h,
                  color: Color(0xfff2f2f2),
                  child: Row(
                    children: [
                      Expanded(
                        child: Padding(
                          padding: EdgeInsets.only(left: 20.w, right: 20.w),
                          child: TextField(
                            controller: _textEditingController,
                            maxLines: 1,
                            style: TextStyle(
                              fontSize: 28.sp,
                              color: Colours.main_text,
                            ),
                            decoration: InputDecoration(
                              hintStyle: TextStyle(
                                fontSize: 28.sp,
                                color: Colours.secondary_text,
                              ),
                              hintText: '请输入小区/写字楼等进行搜索',
                              isDense: true,
                              border: InputBorder.none,
                            ),
                          ),
                        ),
                      ),
                      IconButton(
                          icon: Image.asset(
                            'images/search_icon_gray.png',
                            width: 37.w,
                            height: 37.w,
                          ),
                          onPressed: () {
                            String text = _textEditingController.text.toString();
                            if (text != null && text.trim() != null) {
                              suggestion(text, _city.value, move: true);
                            } else {
                              Toast.show('搜索内容不能为空', context);
                            }
                          })
                    ],
                  ),
                ),
              ),
            ],
          ),
        ),
        Expanded(
          child: Stack(
            children: [
              Container(
                child: generateMap(_options),
                margin: EdgeInsets.only(bottom: 480.h),
              ),
              Align(
                alignment: Alignment.bottomCenter,
                child: Container(
                  height: 500.h,
                  decoration: BoxDecoration(
                    color: Theme.of(context).backgroundColor,
                    borderRadius: BorderRadius.only(
                      topLeft: Radius.circular(20.w),
                      topRight: Radius.circular(20.w),
                    ),
                  ),
                  child: ValueListenableProvider<BDMapData>.value(
                    value: _listData,
                    builder: (context, _) {
                      var data = context.watch<BDMapData>();
                      if (data != null && data.result != null && data.result.length > 0) {
                        return LocationListWidget(
                          data: data,
                          showDistance: widget.showDistance,
                          onClick: (data) {
                            Navigator.pop(context, data);
                          },
                        );
                      } else {
                        return Container(
                          child: Column(
                            children: [
                              Padding(
                                padding: EdgeInsets.only(top: 50.h),
                                child: Image.asset(
                                  'images/null_icon.png',
                                  width: 237.w,
                                  height: 152.w,
                                ),
                              ),
                              Padding(
                                padding: EdgeInsets.only(top: 15.h),
                                child: Text(
                                  '在搜索框内搜索相关信息',
                                  style: TextStyle(
                                    fontSize: 24.sp,
                                    color: Colours.main_text,
                                  ),
                                ),
                              ),
                            ],
                          ),
                        );
                      }
                    },
                  ),
                ),
              ),
            ],
          ),
        ),
      ],
    );
  }

  int count = 0;

  @override
  void initState() {
    super.initState();
    _locationPlugin.onResultCallback().listen((event) {
      if (initLocationBool) return;
      var code = event['errorCode'];
      if (code != null) {
        Toast.show('请确认开启定位权限，否则我无法获取到定位信息！', context);
        location.value = MapType.PERMISSION_FAIL;
        _locationPlugin.stopLocation();
        return;
      }
      _baiduLocation = BaiduLocation.fromMap(event);
      if (_baiduLocation.city == null && _baiduLocation.city.trim() == '') {
        count++;
        if (count > 10) {
          count = 0;
          location.value = MapType.LOCATION_FAIL;
          _locationPlugin.stopLocation();
        }
        return;
      }
      initLocationBool = true;
      _city.value = _baiduLocation.city.toString();
      location.value = MapType.LOCATION_SUCCESS;
      _locationPlugin.stopLocation();
      var data = _baiduLocation?.poiList?.split(',');
      if (data != null && data.length > 0) {
        suggestion(data[0], _baiduLocation.city);
      }
      BMFCoordinate coordinate = BMFCoordinate(_baiduLocation.latitude, _baiduLocation.longitude);
      _options = BMFMapOptions(
        mapType: BMFMapType.Standard,
        scrollEnabled: true,
        zoomLevel: 19,
        minZoomLevel: 4,
        maxZoomLevel: 21,
        logoPosition: BMFLogoPosition.RightTop,
        center: coordinate,
      );
    });
  }

  @override
  void dispose() {
    super.dispose();
    _locationPlugin.stopLocation();
  }

  @override
  Widget build(BuildContext context) {
    initLocation();
    return Scaffold(
      resizeToAvoidBottomPadding: false,
      backgroundColor: Theme.of(context).backgroundColor,
      appBar: PreferredSize(
        preferredSize: Size(double.infinity, 96.h),
        child: Container(
          color: Theme.of(context).backgroundColor,
          child: SafeArea(
            child: Column(
              children: [
                Row(
                  children: <Widget>[
                    MySubassembly.getBackIcon(context,
                        color: Theme.of(context).textTheme.subtitle2.color),
                    Expanded(
                      child: Center(
                        child: Text(
                          StringResources.di_zhi_ding_wei,
                          style: TextStyle(
                              fontSize: 32.sp,
                              fontWeight: FontWeight.w500,
                              color: Theme.of(context).textTheme.subtitle2.color),
                        ),
                      ),
                    ),
                    MySubassembly.getSearchIcon(null, text: Constants.empty),
                  ],
                ),
                Divider(height: 1.h)
              ],
            ),
          ),
        ),
      ),
      body: ValueListenableProvider<MapType>.value(
        value: location,
        builder: (context, _) {
          var type = context.watch<MapType>();
          Widget widget;
          switch (type) {
            case MapType.LOADING:
              widget = LoadingWidget();
              break;
            case MapType.PERMISSION_FAIL:
              widget = FailWidget(
                title: '定位异常',
                content: '请确认定位权限是否添加，定位是否打开！',
                button: '重试',
                onClick: () => initLocation(),
              );
              break;
            case MapType.PERMISSION_SUCCESS:
              widget = LoadingWidget();
              break;
            case MapType.LOCATION_SUCCESS:
              widget = mainView();
              break;
            case MapType.LOCATION_FAIL:
              widget = FailWidget(
                  title: '定位失败',
                  content: '请确保打开定位功能正常使用',
                  onClick: () {
                    initLocation();
                  });
              break;
          }
          return widget;
        },
      ),
    );
  }

  Widget generateMap(BMFMapOptions options) {
    return BMFMapWidget(
      onBMFMapCreated: (controller) async {
        _controller = controller;
        if (widget.showDistance) {
          for (var polygon in widget.locationList) {
            _controller.addPolygon(
                BMFPolygon(coordinates: polygon, width: 4, fillColor: Color(0x330C8AA3)));
          }
        }
        var state = await _controller.getMapStatus();
        BMFMarker marker = BMFMarker(
          isLockedToScreen: true,
          position: BMFCoordinate(state.targetGeoPt.latitude, state.targetGeoPt.longitude),
          icon: 'images/icon_mark.png',
        );
        _controller.addMarker(marker);
        _controller.setMapRegionDidChangeWithReasonCallback(
            callback: (BMFMapStatus mapStatus, BMFRegionChangeReason regionChangeReason) {
          marker.updatePosition(
              BMFCoordinate(mapStatus.targetGeoPt.latitude, mapStatus.targetGeoPt.longitude));
          reveres("${mapStatus.targetGeoPt.latitude},${mapStatus.targetGeoPt.longitude}");
        });
      },
      mapOptions: options,
    );
  }

  void initLocation() async {
    bool data = await _locationPlugin.requestPermission();
    if (data) {
      location.value = MapType.PERMISSION_SUCCESS;
      _setLocOption();
      _locationPlugin.startLocation();
    } else {
      location.value = MapType.PERMISSION_FAIL;
      Toast.show('缺少定位权限', context);
    }
  }

  /// 设置android端和ios端定位参数
  void _setLocOption() {
    /// android 端设置定位参数
    BaiduLocationAndroidOption androidOption = BaiduLocationAndroidOption();
    androidOption.setCoorType("bd09ll"); // 设置返回的位置坐标系类型
    androidOption.setIsNeedAltitude(true); // 设置是否需要返回海拔高度信息
    androidOption.setIsNeedAddres(true); // 设置是否需要返回地址信息
    androidOption.setIsNeedLocationPoiList(true); // 设置是否需要返回周边poi信息
    androidOption.setIsNeedNewVersionRgc(true); // 设置是否需要返回最新版本rgc信息
    androidOption.setIsNeedLocationDescribe(true); // 设置是否需要返回位置描述
    androidOption.setOpenGps(true); // 设置是否需要使用gps
    androidOption.setLocationMode(LocationMode.Hight_Accuracy); // 设置定位模式
    androidOption.setScanspan(1000); // 设置发起定位请求时间间隔

    Map androidMap = androidOption.getMap();

    /// ios 端设置定位参数
    BaiduLocationIOSOption iosOption = BaiduLocationIOSOption();
    iosOption.setIsNeedNewVersionRgc(true); // 设置是否需要返回最新版本rgc信息
    iosOption.setBMKLocationCoordinateType("BMKLocationCoordinateTypeBMK09LL"); // 设置返回的位置坐标系类型
    iosOption.setActivityType("CLActivityTypeAutomotiveNavigation"); // 设置应用位置类型
    iosOption.setLocationTimeout(10); // 设置位置获取超时时间
    iosOption.setDesiredAccuracy("kCLLocationAccuracyBest"); // 设置预期精度参数
    iosOption.setReGeocodeTimeout(10); // 设置获取地址信息超时时间
    iosOption.setDistanceFilter(100); // 设置定位最小更新距离
    iosOption.setAllowsBackgroundLocationUpdates(true); // 是否允许后台定位
    iosOption.setPauseLocUpdateAutomatically(true); //  定位是否会被系统自动暂停

    Map iosMap = iosOption.getMap();

    _locationPlugin.prepareLoc(androidMap, iosMap);
  }

  //通过经纬度定位地址
  void reveres(String location) {
    if (getReveres) return;
    getReveres = true;
    HttpUtil.get(
            'http://api.map.baidu.com/reverse_geocoding/v3/?ak=${Constants.BD_KEY}&output=json&location=$location&extensions_poi=1')
        .then((value) {
      if (value.statusCode == 200) {
        var map = JsonDecoder().convert(value.data);
        var data = Reveres.fromJson(map);
        var pois = data?.result?.poiRegions;
        if (pois != null && pois.length > 0) {
          if (pois != null) {
            _city.value = data.result.addressComponent.city;
            suggestion(pois[0].name, data.result.addressComponent.city);
          }
        }
      }
      getReveres = false;
    }, onError: (e) {
      getReveres = false;
    });
    getReveres = false;
  }

  //搜索地址
  void suggestion(String msg, String city, {bool move = false}) {
    if (getSuggestion) return;
    getSuggestion = true;
    HttpUtil.get(
            'http://api.map.baidu.com/place/v2/suggestion?query=$msg&region=$city&city_limit=true&output=json&ak=${Constants.BD_KEY}')
        .then((value) async {
      if (value.statusCode == 200) {
        var map = JsonDecoder().convert(value.data);
        var data = BDMapData.fromJson(map);
        var list = data?.result;
        if (list != null && list.length > 0) {
          if (widget.showDistance) {
            for (var res in list) {
              res.beyond = false;
              for (var list in widget.locationList) {
                if (res.location != null) {
                  var isBeyond = await BMFCalculateUtils.polygonContainsCoordinate(
                      BMFCoordinate(res.location.lat, res.location.lng), list);
                  if (isBeyond) {
                    res.beyond = isBeyond;
                    break;
                  }
                }
              }
            }
            list.sort((a, b) {
              if (a.beyond) {
                return -1;
              } else {
                return 1;
              }
            });
            if (move) {
              var location = list[0].location;
              _controller?.setCenterCoordinate(BMFCoordinate(location.lat, location.lng), true,
                  animateDurationMs: 1);
            }
          }
        }
        _listData.value = data;
      }
      getSuggestion = false;
    }, onError: (e) {
      getSuggestion = false;
      Toast.show("查询失败", context);
    });
  }
}
